package cn.hc.ddl2;

import cn.hc.conn1.HBaseConnection2;
import org.apache.hadoop.hbase.NamespaceDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;

import java.io.IOException;

/**
 * @author huangchao E-mail:fengquan8866@163.com
 * @version 创建时间：2024/10/8 16:40
 */
public class HBaseDDL1 {

    public static Connection connection = HBaseConnection2.connection;

    /**
     * 创建命名空间
     *
     * @param namespace
     */
    public static void createNamespace(String namespace) throws IOException {
        // 1.获取admin
        // admin的连接是轻量级的，不是线程安全的，不推荐池化或缓存
        Admin admin = connection.getAdmin();

        try {
            // 2.调用方法创建命名空间
            admin.createNamespace(NamespaceDescriptor
                    .create(namespace)
                    .addConfiguration("user", "at")
                    .build());
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 3.关闭admin
        admin.close();
    }

    /**
     * 判断表格是否存在
     *
     * @param namespace 命名空间名称
     * @param tableName 表格名称
     * @return
     * @throws IOException
     */
    public static boolean isTableExist(String namespace, String tableName) throws IOException {
        Admin admin = connection.getAdmin();
        try {
            return admin.tableExists(TableName.valueOf(namespace, tableName));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            admin.close();
        }
        return false;
    }

    /**
     * 创建表格
     *
     * @param namespace      命名空间
     * @param tableName      表名
     * @param columnFamilies 列簇
     */
    public static void createTable(String namespace, String tableName, String... columnFamilies) throws IOException {
        if (columnFamilies.length == 0) {
            System.out.println("创建表格至少有一个列");
            return;
        }

        if (isTableExist(namespace, tableName)) {
            System.out.println("表格已经存在");
            return;
        }

        Admin admin = connection.getAdmin();

        TableDescriptorBuilder builder = TableDescriptorBuilder
                .newBuilder(TableName.valueOf(namespace, tableName));

        for (String columnFamily : columnFamilies) {
            builder.setColumnFamily(ColumnFamilyDescriptorBuilder
                    .newBuilder(Bytes.toBytes(columnFamily))
                    .setMaxVersions(5) // 版本
                    .build());
        }

        try {
            admin.createTable(builder
                    .build());
        } catch (Exception e) {
            e.printStackTrace();
        }

        admin.close();
    }

    /**
     * 修改表格中每个列簇的版本
     *
     * @param namespace    命名空间
     * @param tableName    表名
     * @param columnFamily 列簇
     * @param version      版本
     */
    public static void modifyTable(String namespace, String tableName, String columnFamily, int version) throws IOException {
        if (!isTableExist(namespace, tableName)) {
            System.out.println("表格不存在");
            return;
        }

        Admin admin = connection.getAdmin();

        // 获取老的表描述
        TableDescriptor descriptor = admin.getDescriptor(TableName.valueOf(namespace, tableName));
        // 获取老的列描述
        ColumnFamilyDescriptor columnFamilyDescriptor = descriptor.getColumnFamily(Bytes.toBytes(columnFamily));

        if (columnFamilyDescriptor == null) {
            System.out.println("列不存在");
            return;
        }

        try {
            // 报错：Column family 'info' does not exist
            // 使用这种写法，相当于创建了一个新的表格描述建造者，没有之前的信息
            // 要想修改之前的信息，必须调用方法填写一个旧的表格描述
//            TableName.valueOf(namespace, tableName)
//            ColumnFamilyDescriptor columnFamilyDescriptor = ColumnFamilyDescriptorBuilder
//                    .newBuilder(Bytes.toBytes(columnFamily))
//                    .setMaxVersions(version)
//                    .build();

            admin.modifyTable(TableDescriptorBuilder
                    .newBuilder(descriptor)
                    .modifyColumnFamily(
                            ColumnFamilyDescriptorBuilder.newBuilder(columnFamilyDescriptor)
                                    .setMaxVersions(version)
                                    .build())
                    .build());
        } catch (IOException e) {
            e.printStackTrace();
        }

        admin.close();
    }

    /**
     * 删除表格
     *
     * @param namespace
     * @param tableName
     * @return
     */
    public static boolean deleteTable(String namespace, String tableName) throws IOException {
        if (!isTableExist(namespace, tableName)) {
            System.out.println("表格不存在，不需要删除");
            return false;
        }

        Admin admin = connection.getAdmin();

        try {
            // 删除之前必须disable
            TableName tableName1 = TableName.valueOf(namespace, tableName);
            admin.disableTable(tableName1);

            admin.deleteTable(tableName1);
        } catch (Exception e) {
            e.printStackTrace();
        }

        admin.close();
        return true;
    }

    public static void main(String[] args) throws IOException {
        // 测试创建命名空间
        createNamespace("hc");

        // 测试 表格是否存在
        System.out.println("表格是否存在：" + isTableExist("bigdata", "student"));

        // 测试：创建表格
        createTable("hc", "student", "info", "msg");

        // 测试：修改表格
        modifyTable("hc", "student", "info", 6);
        modifyTable("hc", "student", "info11", 6);

        // 测试：删除表格
        deleteTable("hc", "student11");
        deleteTable("hc", "student");

        // 其他代码
        System.out.println("其他代码");

        HBaseConnection2.closeConnection();
    }
}
